package top.ysez.controller;

import java.util.Date;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

// execute方法
public class Thread04Teacher {

  private static volatile boolean flag = true;

  public static void main(String[] args) throws InterruptedException {
    ThreadPoolExecutor executor =
        new ThreadPoolExecutor(
            2,
            4,
            20,
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(6),
            Executors.defaultThreadFactory(),
            new ThreadPoolExecutor.AbortPolicy() // 默认拒绝策略，直接丢弃任务并抛出异常
            //                new ThreadPoolExecutor.CallerRunsPolicy() //提交任务的线程自己执行这个任务
            //  new ThreadPoolExecutor.DiscardOldestPolicy() // 从队列中删除等待时间最久的任务，不抛出异常
            //                new ThreadPoolExecutor.DiscardPolicy() //直接抛弃最新的任务，不抛出异常

            );

    for (int i = 0; i < 15; i++) {
      try {
        executor.execute(new Mythread("t" + i));
        Thread.sleep(1000);
      } catch (Exception e) {
        System.out.println("exception：" + Thread.currentThread().getName() + "::" + e.getMessage());
        //                如果抛出异常说明已经触发了拒绝策略，此时修改flag，让所有任务执行完毕
        flag = false;

      } finally {
        System.out.println(
            "正在执行任务的线程数:"
                + executor.getActiveCount()
                + ":当前池中的线程总数:"
                + executor.getPoolSize()
                + ":设置的核心线程数:"
                + executor.getCorePoolSize()
                + ":设置的最大线程数:"
                + executor.getMaximumPoolSize()
                + ":池中达到过的最大线程数:"
                + executor.getLargestPoolSize()
                + ":已经完成任务数:"
                + executor.getCompletedTaskCount()
                + ":等待队列中的任务数:"
                + executor.getQueue().size());
      }
    }
    System.out.println("===========" + new Date() + "============");
    for (int i = 0; i < 10; i++) {
      Thread.sleep(2000);
      System.out.println(
          "正在执行任务的程数:"
              + executor.getActiveCount()
              + ":当前池中的线程总数:"
              + executor.getPoolSize()
              + ":设置的核心线程数:"
              + executor.getCorePoolSize()
              + ":设置的最大线程数:"
              + executor.getMaximumPoolSize()
              + ":池中达到过的最大线程数:"
              + executor.getLargestPoolSize()
              + ":已经完成任务数:"
              + executor.getCompletedTaskCount()
              + ":等待队列中的任务数:"
              + executor.getQueue().size());
      System.out.println("*****" + new Date() + "*****");
    }

    // 如果执行到这里flag还是true，那么说明执行的拒绝策略为DiscardOldestPolicy或者
    // 此时把flag设置为false，让所有的线程把任务执行完毕
    /*    if (flag) {
      flag = false;
      Thread.sleep(1000);
      System.out.println("========所有任务都执行完后，再次查看线程池的状态：==========");
      for (int i = 0; i < 5; i++) {
        System.out.println("&&&&&&&&&&&&" + new Date() + "&&&&&&&&&&&&");
        Thread.sleep(6000);
        System.out.println(
            "正在执行任务的程数:"
                + executor.getActiveCount()
                + ":当前池中的线程总数:"
                + executor.getPoolSize()
                + ":设置的核心线程数:"
                + executor.getCorePoolSize()
                + ":设置的最大线程数:"
                + executor.getMaximumPoolSize()
                + ":池中达到过的最大线程数:"
                + executor.getLargestPoolSize()
                + ":已经完成任务数:"
                + executor.getCompletedTaskCount()
                + ":等待队列中的任务数:"
                + executor.getQueue().size());
      }
    }

    executor.shutdown();*/
  }

  static class Mythread implements Runnable {

    private String taskName;

    public Mythread(String taskName) {
      this.taskName = taskName;
    }

    @Override
    public void run() {
      // 如果main线程执行这个任务，说明已经执行了拒绝策略，CallerRunsPolicy，
      // 此时可以把flag设置为false,让所有的线程把任务执行完毕（因为已经看到了拒绝策略的执行）
      if ("main".equals(Thread.currentThread().getName())) {
        flag = false;
      }
      // main线程以外 的其他线程执行到这里都进行死循环，为了观察线程池如何触发拒绝策略
      while (flag) {}
      System.out.println(
          "thread:" + Thread.currentThread().getName() + "::" + "taskName:" + taskName + ":+执行完毕:");
    }
  }
}
